#include <QPluginLoader>

#include "node.h"
#include "taskmanager.h"
#include "interface.h"

#include "session.h"

QString Session::__error_message = QString();

Session::Session(TopModule *top_module, int jobs, bool shuffle) :
    __top_module(top_module),
    __task_manager(new TaskManager(shuffle, jobs)),
    __session_step(0)
{
    // Set the task list to task manager.
    __task_manager->set_task_list(__top_module->all_tasks());
}

Session::~Session()
{
    //Clear the top module.
    delete __task_manager;
    delete __top_module;
}

Session *Session::create_session(const QString &plugin_path,
                                 bool shuffle, int jobs)
{
    // Load the plugin from the string.
    QPluginLoader loader(plugin_path);
    QObject *module_plugin = loader.instance();
    if(!module_plugin)
    {
        __error_message = loader.errorString();
        return nullptr;
    }
    // Cast into Juna interface.
    JunaInterface *interface = qobject_cast<JunaInterface *>(module_plugin);
    // Based on the interface, create the Session.
    TopModule *module = interface->top_module();
    // Check module pointer.
    if(!module)
    {
        __error_message = "Null top module pointer returned.";
        return nullptr;
    }
    return new Session(module, jobs, shuffle);
}

QString Session::error_message()
{
    return __error_message;
}

void Session::n()
{
    next_step();
}

void Session::next_n_step(int n)
{
    // Run n steps.
    __task_manager->run(n);
    // Increase the session for n steps.
    __session_step += n;
}

void Session::ns(int n)
{
    next_n_step(n);
}

void Session::nn(int n)
{
    next_n_step(n);
}

void Session::next_step()
{
    // Run 1 step.
    __task_manager->run();
    // Increase the session step.
    ++__session_step;
}
